#ifndef __MEDIATOR_H__
#define __MEDIATOR_H__
#include<iostream>
#include<string>
#include<memory>
#include<list>

class Colleague;

class Mediator{
public:
    virtual ~Mediator(){ std::cout << "~Mediator" << std::endl;}
    virtual void registColleague(std::shared_ptr<Colleague>& colleague) = 0;
    virtual void ColleagueChanged(const std::string& msg,const std::shared_ptr<Colleague>& colleague) = 0;
};

class ConCreteMediator:public Mediator{
private:
    std::list<std::shared_ptr<Colleague>> m_colleagues;
public:
    virtual ~ConCreteMediator(){std::cout << "~ConCreteMediator" << std::endl;}
    virtual void registColleague(std::shared_ptr<Colleague>& colleague);
    virtual void ColleagueChanged(const std::string& msg,const std::shared_ptr<Colleague>& colleague);
};


class Colleague{
public:
    virtual ~Colleague(){std::cout << "~Colleague" << std::endl;}
    virtual void send(const std::string& msg) = 0;
    virtual void recieve(const std::string& msg) = 0;   
};

class ConcreteCollegue : public Colleague,public std::enable_shared_from_this<ConcreteCollegue>{
public:
    ConcreteCollegue(std::string name,std::shared_ptr<Mediator>& media):m_name(name),m_mediator(media){}
    virtual ~ConcreteCollegue(){std::cout<<"~ConcreteCollegue" << std::endl;}
    void send(const std::string& msg);
    void recieve(const std::string& msg);
private:
    std::string m_name;
    std::weak_ptr<Mediator> m_mediator;

};



#endif